# FreeBSD installation guide

Tested with FreeBSD 13.0-RELEASE (amd64). This is tested on a flash drive so it appeared as `/dev/da*`. When installing on non-removable drives however, it may appear as `/dev/ada*`, but instructions remain more or less the same.

**WARNING:** FreeBSD has nonfree packages on the repository. Installing and running them can harm your user freedom. These instructions are tested once or twice and have not been used in production. So use with caution.

**Requirements:**
- FreeBSD supported computer connected to internet
- 1 USB flash drive for livecd installer
- 1 storage media for installation (which is also a flash drive in my case)

## Step 1: Installation prep

Download memstick or memstick-mini FreeBSD image from [FreeBSD's download page](https://www.freebsd.org/where/). I prefer the .xz variant because it's a much smaller download. (e.g. `FreeBSD-13.0-RELEASE-amd64-mini-memstick.img.xz`.)

Also download the checksum file (e.g. `CHECKSUM.SHA512-FreeBSD-13.0-RELEASE-amd64`) and verify that the image is ok:

```sh
sha512sum --ignore-missing -c CHECKSUM.SHA512-FreeBSD-13.0-RELEASE-amd64
```

It should show an OK message. If it isn't, the file may have been tampered with by unauthorized entity. Please use [torrent](https://fosstorrents.com) or other medium to get a fresh and valid copy of the image.

Now write the image to your flash drive:

```
# From FreeBSD
xzcat FreeBSD-13.0-RELEASE-amd64-mini-memstick.img.xz | sudo dd of=/dev/daX bs=1m
# From GNU+Linux
xzcat FreeBSD-13.0-RELEASE-amd64-mini-memstick.img.xz | sudo dd of=/dev/sdX bs=1M
```

## Step 2: Installation

Boot into the flash drive and install as usual.

When asked for filesystem setup choose **Auto (UFS)**. [ **WARNING**: Keep in mind that selecting **Auto** option will wipe out the entire storage device with all partitions and everything. ] If you want to install it alongside Linux check the "Install FreeBSD alongside Linux" heading below and then continue from here.

I chose MBR, but it should work with GPT as well.

When creating a user, I usually add it to groups `wheel network video`.

### Using UFS IDs and labels

FreeBSD installer does not use UUIDs or UFS IDs to identify them. So if you disconnect some other device or plug it into a different port, it can't find the filesystem. To fix that we'd have to use UUIDs and labels instead of the default `/dev/` identifiers. If we do this we'd be able to insert the media into any port or any other computer and it will still work.

After the installation completes, you select "Exit" and there is a prompt saying "...Before exiting the installer, would you like to open a shell in the new system...?" - choose yes.

It will start a chroot interface into the new install. Run `mount` to see where `/mnt` is mounted. This is where our installation root filesystem is. Mine was at `da1s1a`, so I ran:

```sh
dumpfs -l /dev/da1s1a # to see if you can get the ufsid
cp /etc/fstab /etc/fstab.bak # to keep backup of the original
dumpfs -l /dev/da1s1a >> /etc/fstab
```

Since I chose Auto (UFS) it created a swap partition on `/dev/da1s1b` as well. So I gave it a label (it seems I wasn't able to get UUIDs for swap):

```sh
glabel label bsdswap /dev/da1s1b
```

So now we'd edit out /etc/fstab to reflect those values:

```sh
edit /etc/fstab
```

Place your cursor right after `/dev/da1s1a`, press Ctrl+K to cut and then immediately Ctrl+L uncut. You'd notice there is a ufsid at the end of the file. Place your cursor right after the id and press Ctrl+L to uncut.

Now place your cursor at the beginning of `/dev/da1s1b` (swap line), press Ctrl+K, Ctrl+L, then again Ctrl+L to have a copy of the line. In one of the lines, replace `/dev/da1s1b` with `/dev/label/bsdswap`.

Comment out the `/dev/da1s1*` lines by adding a `#` before the lines. Your /etc/fstab should now entries like this:

```
...
# root
/dev/ufsid/6XXXXXXXXXXXXXX8	/	ufs	rw	1	1
# swap
/dev/label/bsdswap	none	swap	sw	0	0
```

To save and exit, press Esc, Enter, Enter. Then run `reboot` to boot into your installation.

### Install FreeBSD alongside Linux

With manual partitioning first "Create" a partition of type `freebsd` keeping mountpoint empty. This will create a "slice", which is like a "partition". Now we need to create a filesystem inside that slice or partition. So select that slice and select "Create" again and create the filesystem as you would. e.g. `freebsd-ufs` filesystem mounted to `/`. To use it alongside other operating systems you can keep the boot in the same filesystem (by not showing a separate /boot partition).

If you chose to install it like this and use GRUB, be sure to check "Boot FreeBSD from GRUB2" section below.

### Boot FreeBSD from GRUB2

In this example I had a Debian GNU+Linux stable install on the same storage device. I already had a working GRUB installation and I installed FreeBSD on a **primary partition**. I just put this on `/etc/grub.d/40_custom` on Debian:

```
...
menuentry "FreeBSD" {
    search --no-floppy --fs-uuid --set=root 633eb3cb8452ca7f
    chainloader +1
}
```
\* `633eb3cb8452ca7f` is the UUID for my freebsd slice. You can find yours how you normally find out UUIDs. e.g. from GNOME Disks or by running `blkid`.

Don't forget to run this to regenerate GRUB menu:
```sh
sudo update-grub
# On Arch/Parabola or some other systems this would be:
sudo grub-mkconfig -o /boot/grub/grub.cfg
```

Select "FreeBSD" from the GRUB menu to boot into FreeBSD. This should work for primary partitions. If it does not work, try this next one.

If you created the `freebsd` slice under an **extended partition** be prepared to face a unbootable device upon restart after setup (for situations like these backups are really handy and necessary). FreeBSD installer partitioner formatted my Debian install. So I had to reinstall Debian. This time I added something like this to `/etc/grub.d/40_custom`:

```
...
menuentry "FreeBSD" {
    insmod ufs2
    search --no-floppy --fs-uuid --set=root 633eb3cb8452ca7f
    kfreebsd /boot/loader
}
```

If you are more comfortable with labels (or for some reason UUIDs are not working), enter into FreeBSD's single user mode from boot menu and login to shell. Keep backup of everything important before trying this in case you mess this up somehow. Then:

```sh
# To check disks available and note down boot partition id. We'll need it below.
gpart list disk | less
# Add label to your UFS boot partition. The /dev id will be different in your
# case, so change it according to your note.
# If you want to reuse this for other things, keep in mind that tunefs only works
# for UFS partitions.
tunefs -L 'freebsd_boot' /dev/da0s2+123456
# Use glabel to check if the label has been applied correctly
glabel list | less
# Reboot and boot into Linux to make changes to GRUB menu
reboot
```

Then on GRUB's side:

```
menuentry "FreeBSD" {
    insmod ufs2
    search --no-floppy --label --set=root freebsd_boot
    ...
}
```

Don't forget to regenerate GRUB menu with above `update-grub` or `grub-mkconfig` command.

Source: <https://forums.freebsd.org/threads/booting-freebsd-via-grub.60422/>, <https://unix.stackexchange.com/a/16891>

## Step 3: After boot

After first boot, login as root and run `pkg update`. It will ask `The package management tool is not yet installed on your system. Do you want to fetch and install it now? [y/N]:`. Enter `y` and it will install it. When it completes, run `pkg upgrade`.

Now when I run `df -h /` it says it is only taking 1.2G. Although this is before anything installed. It seems to be a good place to start from the ground up.

By default, there's no nano. I'm not a fan of FreeBSD's `edit` editor. To use bash, sudo and nano just like in GNU+Linux run:

```sh
pkg install -y bash nano sudo
chsh -s bash root
chsh -s bash <your normal username>
```

Now run `bash` and then `EDITOR=nano visudo`, find the line `# %wheel ALL=(ALL) ALL` and remove the `#` before the line and save it (Ctrl+O, Enter, Ctrl+X).

Press Ctrl+D once to logout from bash and again to logout from sh then login as your normal user to confirm if it's working. You will be able to run commands with `sudo` now.

## Step 4: Things to do after install

These are optional. Continue how you like it.

### `pkg` basics

```sh
# install
sudo pkg install somepackage anotherpackage
# add -y to install without yes/no prompt
sudo pkg install -y somepackage anotherpackage
# remove
sudo pkg remove somepackage
sudo pkg autoremove # removes leftover orphan dependencies
# clean downloaded package files
sudo pkg clean -y
```

### Get faster package downloads

```sh
sudo mkdir -p /usr/local/etc/pkg/repos
# to disable the default repo
echo 'FreeBSD: { enabled: no }' | sudo tee /usr/local/etc/pkg/repos/FreeBSD.conf
```

Go to [FreeBSD mirror site](https://pkg.freebsd.org/) and choose an URL from the country nearest to you from under "Other mirrors". You can go into each link to find out which country it is from. e.g. If the chosen URL is `http://pkg0.bme.freebsd.org/` then:

`sudo nano /usr/local/etc/pkg/repos/custom_repo.conf`
```
custom_repo: {
  url: "http://pkg0.bme.freebsd.org/${ABI}/quarterly",
  enabled: yes
}
```

### Install drivers for Intel HD Graphics

"Intel HD Graphics refers to the class of graphics chips that are integrated on the same die as an Intel CPU." This is basically for built in Intel graphics cards.

```sh
sudo pkg install xf86-video-intel
sudo pkg install drm-kmod
# some suggest using the full path to the module
# https://forums.freebsd.org/threads/cant-start-x-anymore-caught-signal-6-abort-trap-server-aborting.86993/
sudo sysrc -f /etc/rc.conf kld_list+="/boot/modules/i915kms.ko"
# make sure your user is in "video" group
sudo pw group mod video -m $USER
sudo reboot  # for group assignment and kld_list to take effect
# if there is high CPU usage or tearing in video:
sudo pkg install libva-intel-driver mesa-libs mesa-dri
```

Please also refer to "Graphics acceleration is disabled after switching to tty" section below.

Source: <https://wiki.freebsd.org/Graphics>

### Graphics acceleration is disabled after switching to tty

This is in case if graphics acceleration gets disabled after swithing to tty and coming back to X11. The issue is with drm-kmod driver (at least in 13.1-RELEASE on January 2023). To reproduce this issue:
- make sure mesa-demos is installed (`sudo pkg install mesa-demos`)
- immediately after starting X11 session run: `glxinfo | grep -i accel`; it should say `Accelerated: yes`
- switch to any tty (e.g. Ctrl+Alt+F3) and back (Ctrl+Alt+F9)
- run `glxinfo | grep -i accel` again
- if it says `Accelerated: no` this time follow the solution below, otherwise ignore this rest of the section

A result of this is that mpv runs in fullscreen mode, without play-pause buttons and it cannot be closed with anything like esc or alt+f4. Running from terminal may show something like:

```
...
error: XDG_RUNTIME_DIR is invalid or not set in the environment.
libEGL warning: DRI2: failed to authenticate
[vo/gpu/opengl] Suspected software renderer or indirect context.
[vo/gpu] VT_GETMODE failed: Inappropriate ioctl for device
[vo/gpu/opengl] Failed to set up VT switcher. Terminal switching will be unavailable.
WARNING: Kernel has no file descriptor comparison support: Operation not supported by device
...
```

If you run into this situation and can't quit mpv, try going to a tty (it may show nothing you do on screen but it will work on background), login and run `pkill mpv`.

#### The solution to tty switching problem

Follow this only if above steps show that the issue exists.

<https://github.com/freebsd/drm-kmod/issues/175> suggests installing `drm-54-kmod-5.4.191_1`. There are other ways of course but here's how I installed `5.4.92` and solved the issue:

**WARNING:** This has been tested on FreeBSD 13.1-RELEASE and using these exact commands may cause issues if used on any other version. Use carefully. This may break your system, so do proper backups before trying.

I was running 13.1-RELEASE, so I changed repo on `/usr/local/etc/pkg/repos/custom_repo.conf` from, for example, `url: "http://pkg0.kul.freebsd.org/${ABI}/latest",` to `url: "http://pkg0.kul.freebsd.org/${ABI}/release_0",`

```
sudo pkg update  # to update repo records for release_0
pkg search drm  # check whether drm-fbsd13-kmod-5.4.x exists
sudo pkg install drm-fbsd13-kmod
sudo pkg lock drm-fbsd13-kmod  # so that the package cannot be updated/removed without unlocking it
pkg lock -l  # to confirm if the package is listed as locked
```

Revert the changes in `/usr/local/etc/pkg/repos/custom_repo.conf` to make it like before, then update and reboot:

```
sudo pkg update  # to update repo records for reverted repo url
sudo reboot
```

If you have `vo` or `hwdec` set in `~/.config/mpv/mpv.conf`, remove them because they should not be needed anymore.

When the linked above issue is solved and the fix is available on your FreeBSD version, unlock package with (`sudo pkg unlock drm-fbsd13-kmod`), and upgrade (`sudo pkg update && sudo pkg upgrade`).


### Stop creating .core files

FreeBSD might create some .core files (such as jgmenu.core, firefox.core, inkscape.core) in `$HOME`.

`sudo nano /etc/sysctl.conf` and add:
```
...
kern.coredump=0
```

To apply it on current session:
```sh
sudo sysctl kern.coredump=0
```

Source: <https://forums.freebsd.org/threads/core-files.17761/>


### Machine heating too much

<https://wiki.freebsd.org/TuningPowerConsumption> is the first thing to check out. It should dramatically improve the situation. Some changes improve battery life too.

Second would be to use powerd. Something like this in `/etc/rc.conf` may do the trick:

```
powerd_enable="YES"
powerd_flags="-n hiadaptive -a hiadaptive -b adaptive -m 800 -M 1400" # change -m and -M values based on your cpu
```

It will slow the cpu down to make it heat less. So you might experience the machine slowing down a bit.

The above two should be enough. Use this for a while to check if the heating issue improves. If it doesn't, try to tweak values and see if it works.

If still no use, another solution is to use powerdxx. According to `man powerdxx`:

```
The powerd++ daemon monitors the system load and adjusts the CPU clock
     speed accordingly.  It is a drop-in replacement for powerd(8)...
```

To use it, install powerdxx, disable and stop powerd (if enabled), enable and start powerdxx:

```sh
sudo pkg install powerdxx
sudo sysrc powerd_enable=NO
sudo service powerd stop
sudo sysrc powerdxx_enable=YES
sudo service powerdxx start
```

Command line arguments can be added with `powerdxx_flags` in rc.conf:

```sh
sudo sysrc powerdxx_flags="--ac hadp --batt hadp"
```

You may need to enable corresponding acpi module for your machine. For example for ThinkPad:

```sh
sudo kldload acpi_ibm
```

To make the change stay on next boot, you may need to add the following to `/boot/loader.conf`:

```
acpi_ibm_load="YES"
```

Run `ls /boot/kernel/acpi_*` to see all the options.

`sudo sysctl hw.acpi` can be used to see information about acpi variables.

### `bash-completion` for completing parts of command with tab

```sh
sudo pkg install bash-completion
```

Then according to install message add the following to your `~/.bashrc` file:

```sh
[[ $PS1 && -f /usr/local/share/bash-completion/bash_completion.sh ]] && \
	source /usr/local/share/bash-completion/bash_completion.sh
```

### Automatically connect an interface

Add to `/etc/rc.conf` a line `ifconfig_<interface>="DHCP"`. e.g.

```
ifconfig_ue0="DHCP"
```

### Automatically connect an interface with speed modifications

Add to `/etc/rc.conf` a line like this:

```
ifconfig_ue0="DHCP inet 192.168.199.197 netmask 255.255.255.0 media 10baseT/UTP mediaopt full-duplex"
```

- `ue0` is the interface name, which may be different based on your device.
- `192.168.199.` being the first part of the IP you use to access router admin panel. `197` is just a free random IP number. Change if necessary.
- `10baseT/UTP` means 10mbps [unshielded twisted-pair (UTP)](https://web.archive.org/web/https://networkencyclopedia.com/10baset/) speed setting. This can be `100baseTX`, `1000baseTX` etc. depending on device. See output of `ifconfig -m` and check "supported media:" options under your interface. It should show something like:
```
...
        supported media:
                media autoselect
                media 10baseT/UTP
                media 100baseTX
                media 1000baseT
```
- `full-duplex` can also be `half-duplex`, but check `ifconfig -m`, `man em`, `man rl` etc. (based on your card) to see which one is supported for your speed setting.

Source: <https://www.cyberciti.biz/faq/howto-configure-freebsd-full-half-duplex-speed/>, `man ifconfig` and `man rc.conf` for details.

### List open ports

```sh
sockstat -l
```

Also:
```sh
sockstat -4l # IPv4 ports only
sockstat -6l # IPv6 ports only
```

### `~/.bash_aliases`

Create a `~/.bash_aliases` file with aliases or use [this one](https://notabug.org/adnan360/code-backups/src/master/bash/.bash_aliases). Then:

`nano ~/.profile`
```sh
...
source ~/.bash_aliases
```

To save, press Ctrl+O then Enter, Ctrl+X to exit. Logout and login to test if this works. Add this code also to `~/.bashrc` (create if doesn't exist) to use aliases on graphical terminal sessions.

### Install git

```sh
sudo pkg install -y git-lite
```

There is a `git` package, but `git-lite` should be enough for most people.

### Install a GUI desktop

```sh
sudo pkg install xorg
sudo pw group mod video -m <your normal username>
```

Now running `startx` should run twm with bunch of terminals. Hover your mouse over each terminal and press Ctrl+D until you are back to tty.

Now install the desktop you want. For example if you want Openbox:

```sh
sudo pkg install openbox
```

To use it without any Desktop Manager:

```sh
cp /usr/local/etc/X11/xinit/xinitrc ~/.xinitrc
nano ~/.xinitrc
```

Now scroll at the end and you'll find twm related paragraph of code. Add `#` in front of them and add:

```sh
exec openbox-session
```

This will run when you run `startx` and you won't need any DMs like LightDM, XDM, Slim etc. to login. Run `startx` to test if it's working. Right click, select Logout when done.

You can install a config like [this one](https://notabug.org/adnan360/openbox-config) to get a traditional desktop interface within Openbox.

You can install any desktop environment like this. Just install the package and change the line in `~/.xinitrc`. To determine which exec command to run, check documentation of that DE or search around.

### Auto startx on log in

If you want it to [automatically run startx](https://unix.stackexchange.com/a/443731) when user logs in to tty0, you can add this to `~/.profile`:

```sh
if [ "$(tty)" == "/dev/ttyv0" ]; then
  echo Starting Xorg...
  startx
  echo "Halt (h) Reboot (r) Nothing (n) ?"
  read answer
  if [ $answer == "h" ]; then
    /sbin/shutdown -p now
  elif [ $answer == "r" ]; then
    /sbin/shutdown -r now
  fi
fi
```

One bonus is that when you log out of your desktop environment, it asks you if you want to shutdown, reboot or just drop into shell.

### Network manager tray icon

```sh
sudo pkg install networkmgr
networkmgr &>/dev/null & disown
# optionally run 'networkmgr' on startup
```

I have had some issues with networkmgr not being able to connect to internet. If that happens to you, uninstall it.

### Volume icon on tray

```sh
sudo pkg install volumeicon
volumeicon &>/dev/null & disown
# optionally run 'volumeicon' on startup
```

### GUI volume mixer

```sh
sudo pkg install gtk-mixer
gtk-mixer
```

### Automounting removable drives

```sh
sudo pkg install automount
sudo service devd restart # says on install message
```

This will also install commonly used fuse powered drivers. Run `ls /boot/kernel/fuse*` to check the name of the fuse loader. It gave me `fusefs.ko`, so:

```sh
sudo sysrc kld_list+=fusefs
sudo kldload fusefs
```

To get rid of "Operation not permitted" error while unmounting and use file system labels, try this below:

```sh
echo -e 'USERUMOUNT=YES\nNICENAMES=YES' | sudo tee -a /usr/local/etc/automount.conf
```

Optionally, to configure [check this for example `automount.conf`](https://vermaden.wordpress.com/2018/10/11/freebsd-desktop-part-17-automount-removable-media/).

### Get Trash, FTP, SMB etc. on filemanager

```sh
sudo pkg install gvfs
```

Now add this before the `startx` line in ~/.xinitrc to get trash and possibly [other benefits](https://docs.xfce.org/xfce/thunar/unix-filesystem#gnome_virtual_file_system):

```sh
[ -z "$DBUS_SESSION_BUS_PID" ] && [ -n "$(command -v dbus-launch)" ] && export $(dbus-launch)
```

Then logout and re-login. You should now be able to access FTP sites right within your file manager. e.g. enter `ftp://ftp.freebsd.org/pub/FreeBSD/` or `ftp://speedtest.tele2.net/` ([source](https://stackoverflow.com/questions/7968703/is-there-a-public-ftp-server-to-test-upload-and-download)) on location bar to test this. With [Firefox getting rid of built in FTP support](https://www.ghacks.net/2021/04/16/firefox-90-wont-handle-ftp-sites-anymore/), this is useful to have around.

### Automounting NTFS formatted internal hard disk

Use `automountntfs.sh` script in this directory. Run `gpart show` to check which device you want, usually it's `/dev/ada0`. Then run it with the device `./automountntfs.sh /dev/ada0`.

### Solving boot issues

If you've made a recent change in config or something and can't boot:

- reboot
- press 2 on boot menu to select Single user mode
- when asked for root password, enter it
- when asked for shell, you can press enter
- now run `mount -a` and it will allow you to undo your config changes, e.g. you can run `nano /boot/loader.conf` to fix a loader issue
- run `exit` or press Ctrl+D when done and it should continue the boot process

### Force file system check and repair

Usually the fsck runs automatically on boot. If it doesn't for some reason:

- reboot
- press 2 to enter Single user mode and eventually enter into shell
- without mounting anything run `fsck -fy`
- when done, enter `exit` or press Ctrl+D

### `uhub_reattach_port: giving up port 2 reset - device vanished: change 0x1 status 0x101`

[This message](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=237666) during boot may appear repeatedly in the tty. The reason is not clear. In some cases it shows up after an upgrade and in other cases on the same install possibly due to a small change in config or hardware or something else.

Check output of `sudo dmesg | grep vanished | wc -l`, then run this:

```sh
sudo sysctl hw.usb.disable_enumeration=1
```

**NOTE**: Not sure if this will solve the issue, but it will silence the messages. Running this may cause some devices to not be detected, e.g. plugging in something after boot. So use it only when needed or set it to `0` (zero) temporarily.

Run the above dmesg command a couple of times. If the output number stops increasing, it means it worked. To make this permanent, add the following to `/etc/sysctl.conf`:

```
# to silence repeated "uhub_reattach_port ... device vanished" error
hw.usb.disable_enumeration=1
```

### How to install ports in FreeBSD

**WARNING**: These are untested instructions. Use at your own risk.

Ports are basically "recipes" for packages; instructions on how they should be built. It is used, for example, to install modified versions of packages, to create new packages etc.

If ports are to be used in conjuction to binary packages, ports should be from the same branch as pkg. FreeBSD has a branch for each quarter (where a year has 4 quarters each with 3 months). Branches are named `<year>Q<quarter>`. e.g. 2023Q1, 2023Q2, 2023Q3, 2023Q4, 2024Q1 and so on. A way to check is to run `pkg info pkg` or `pkg --version` and match it with `DISTVERSION` in different branches.

For example:
```sh
curl https://cgit.freebsd.org/ports/plain/ports-mgmt/pkg/Makefile?h=2024Q1 | grep ^DISTVERSION
curl https://cgit.freebsd.org/ports/plain/ports-mgmt/pkg/Makefile?h=2023Q4 | grep ^DISTVERSION
curl https://cgit.freebsd.org/ports/plain/ports-mgmt/pkg/Makefile?h=2023Q3 | grep ^DISTVERSION
curl https://cgit.freebsd.org/ports/plain/ports-mgmt/pkg/Makefile?h=2023Q2 | grep ^DISTVERSION
...
...
```

Stop when you found your match and use that branch name (present in URL) in commands below.

```sh
sudo -s
# Option 1: Quarterly branch (modify 2020Q3 according to above instructions):
git clone https://git.FreeBSD.org/ports.git -b 2020Q3 /usr/ports
# Option 2: HEAD branch (usually not recommended):
git clone https://git.FreeBSD.org/ports.git /usr/ports
```

Further commands:

```sh
# To switch to another branch (for example, if you update to a new pkg version) (modify 2020Q4 accordingly):
git -C /usr/ports switch 2020Q4
# Update the initial pull as needed:
git -C /usr/ports pull
```

If disk space is scarce, a shallow clone can be maintained. Although this may not be ideal in some situations. Commands below also gets rid of other branches, tags etc.

```sh
sudo -s
git clone https://git.FreeBSD.org/ports.git -b 2020Q3 /usr/ports
# to update later:
cd /usr/ports
git pull --depth 1 --rebase
git tag -d $(git tag -l) && git reflog expire --expire=all --all && git gc --prune=all
```

If you want to make a new port, follow this [new-port handbook page](https://docs.freebsd.org/en/books/porters-handbook/new-port/).

Source: <https://docs.freebsd.org/en/books/handbook/ports/#ports-using>

### How to build FreeBSD kernel from source

```
$ doas -s
// Running "doas dmesg | grep '^FreeBSD [0-9]'" will give a hint to kernel
// version currently running.
// It may say something like "releng/14.0-n265380-f9716eee8ab4:"
# git clone --depth 1 -b releng/14.0 -o freebsd https://git.FreeBSD.org/src.git /usr/src
// --depth 1: shallow clone, only last commit (depending on your use-case you might want to drop this)
// -b ...: specify branch
// -o ...: specify origin
```

Now let's create a custom config to build kernel (as it is the most common use case):

```
# cd /usr/src/sys/$(uname -m)/conf
# cp GENERIC MYKERNEL
# nano MYKERNEL
// Change the ident line to "ident MYKERNEL", then do further edits
```

```
# cd /usr/src
# make buildkernel KERNCONF=MYKERNEL
```

It may end with something like:

```
...
--------------------------------------------------------------
>>> Kernel build for MYKERNEL completed on Sun Dec 16 00:28:09 UTC-2 2023
--------------------------------------------------------------
>>> Kernel(s)  MYKERNEL built in XYZ seconds, ncpu: 2
--------------------------------------------------------------
```

Install the kernel with:

```
# make installkernel KERNCONF=MYKERNEL
```

If kernel does not boot, escape to loader prompt, enter "boot kernel.old". You can also use the menu item to do this.

Source: <https://docs.freebsd.org/en/books/handbook/kernelconfig/#kernelconfig-config>

### Use TOR with Firefox

Run `pkg search tor-browser` to see if a `tor-browser` package exists. If it does, install it instead of following the customization guide mentioned afterwards:

```
sudo pkg install tor-browser
```

If there are no packages named `tor-browser` available, Firefox can be made to act close to TOR Browser. It is [not however recommended by the TOR project](https://support.torproject.org/tbb/tbb-9/) to use it that way:

> We strongly recommend against using Tor in any browser other than Tor Browser. Using Tor in another browser can leave you vulnerable without the privacy protections of Tor Browser.

**WARNING:**

This setup would not guarantee same security as TOR Browser and using it for serious work, anonymity or personal safety is not recommended. Also consider using [a jail](https://forums.freebsd.org/threads/how-to-execute-firefox-in-a-jail-using-iocage-and-ssh-jailme.53362/) if you know how to use it.

Straight from [TOR project website](https://support.torproject.org/tbb/tbb-4/):

> Tor Browser is a modified version of Firefox specifically designed for use with Tor. A lot of work has been put into making the Tor Browser, including the use of extra patches to enhance privacy and security. While it is technically possible to use Tor with other browsers, you may open yourself up to potential attacks or information leakage, so we strongly discourage it.

This guide has instructions on installing addons which may [deanonymize you and make you more trackable](https://support.torproject.org/#faq-3):

> Installing new add-ons may affect Tor Browser in unforeseen ways and potentially make your Tor Browser fingerprint unique. If your copy of Tor Browser has a unique fingerprint, your browsing activities can be deanonymized and tracked even though you are using Tor Browser.
> ...
> There's also a good chance a new add-on will increase the attack surface of Tor Browser. This may allow sensitive data to be leaked or allow an attacker to infect Tor Browser. The add-on itself could even be maliciously designed to spy on you.
> Tor Browser already comes installed with one add-on — [NoScript](https://noscript.net/) — and adding anything else could deanonymize you.

```sh
sudo pkg install firefox tor
sudo sysctl net.inet.ip.random_id=1 # set random ip recommended by install message
echo 'net.inet.ip.random_id=1' | sudo tee -a /etc/sysctl.conf # make it permanent
echo 'tor_enable="YES"' | sudo tee -a /etc/rc.conf
sudo service tor start
mkdir ~/bin
cd ~/bin
echo -e '#!/usr/bin/env bash'"\nfirefox --no-remote --profile '/home/$USER/bin/tor-firefox-profile' & disown" > tor-firefox
chmod +x tor-firefox
mkdir tor-firefox-profile
```

The `~/bin/tor-firefox` script will use `~/bin/tor-firefox-profile` directory to store a separate profile for it. So settings, addons etc. will be separate from the system Firefox installation. If you have `~/bin` in `$PATH` (e.g. by adding `export PATH="$PATH:$HOME/bin"` in `~/.bashrc`) you could run `tor-firefox` on terminal from anywhere, but that's optional. We will create a shortcut for it on application menu, so it will be easier to launch. You can use regular firefox from the application menu as usual, but when you run this script, it will run it as a separate instance and use the separate profile directory.

To make it accessible from application menu:

`mkdir -p ~/.local/share/applications/ && nano ~/.local/share/applications/tor-firefox.desktop`
```ini
[Desktop Entry]
Version=1.0
Name=TOR Firefox
Comment=TOR configured Firefox web browser
GenericName=TOR Web Browser
Keywords=Internet;WWW;Browser;Web;Explorer
Exec=~/bin/tor-firefox %U
Terminal=false
Type=Application
Icon=applications-internet
Categories=GNOME;GTK;Network;WebBrowser;
MimeType=text/html;text/xml;application/xhtml+xml;application/xml;application/rss+xml;application/rdf+xml;image/gif;image/jpeg;image/png;x-scheme-handler/http;x-scheme-handler/https;x-scheme-handler/ftp;x-scheme-handler/chrome;video/webm;application/x-xpinstall;
StartupNotify=true
```

In addition to arkenfox user.js script modifications, we need to debrand, disable and clean some stuff:

`nano tor-firefox-profile/user-overrides.js`
```js
// Disable promotional links from Mozilla
user_pref("identity.fxaccounts.enabled", false);
user_pref("browser.preferences.moreFromMozilla", false);
// Disable Pocket extension
user_pref("extensions.pocket.enabled", false);

// Uncheck Privacy & Security>Logins and Passwords>Ask to save logins and passwords for websites
user_pref("signon.rememberSignons", false);
// Uncheck General>Startup>Always check if Firefox is your default browser
user_pref("browser.shell.checkDefaultBrowser", false);
// Uncheck Privacy & Security>Logins and Passwords>Show alerts about passwords for breached websites
user_pref("signon.management.page.breach-alerts.enabled", false);
// Disable Firefox View (the first pinned tab)
user_pref("browser.tabs.firefox-view", false);
// Clear pinned entries
user_pref("browser.newtabpage.pinned", '[{}]');
// Set proxy to TOR
user_pref("network.proxy.type", 1);
user_pref("network.proxy.socks", "127.0.0.1");
user_pref("network.proxy.socks_port", 9050);
user_pref("network.proxy.socks_remote_dns", true);
```

Now to apply user.js changes:

```sh
git clone --depth 1 https://github.com/arkenfox/user.js
user.js/updater.sh -p tor-firefox-profile
```

Now further prepare the TOR Firefox by running `tor-firefox` and then:

**Note:** Old instructions had manual instructions for changing preferences which is not necessary, thanks to user.js project (utilized above). If for some reason those instructions are needed, they are available in [`old-tor-firefox-instructions.md`](old-tor-firefox-instructions.md).

- Optionally, add a "Forget" button on toolbar to easily clear recent history. This is not similar to the New Identity button on TOR Browser toolbar, but it can be clicked and then tor service could be restarted from terminal to get a similar effect. While it may be similar, it may not be the same. To add this button, right click on empty space on the toolbar and select Customize Toolbar..., drag and drop the Forget item to toolbar, click Done.
- Clear cache by pressing Ctrl+Shift+Delete, selecting "Everything" in time range and checking all checkboxes.
- Open Settings/Preferences (Alt+E, N) and apply these changes:

**Search:**
- Change your search engine to at least DuckDuckGo. To select [Searx](https://searx.space/) or [Metager.org](https://metager.org) or any other privacy respecting alternative, right click on location bar and choose to add that search engine. Additionally check [privacyguides.org search engines page](https://www.privacyguides.org/search-engines/) for options. Then select it under Default Search Engine settings.

- Optional, but might be useful:
  - <https://browserleaks.com> displays what data is exposed to websites when you visit them.
  - <https://coveryourtracks.eff.org/> checks how unique your browser is.
  - <https://privacy.net/analyzer/> has a good summary.
  - <https://webbrowsertools.com/privacy-test/> another site for summary, with fingerprint tests.
  - <https://browseraudit.com> tests your browser extensively.
  - <https://proxy6.net/en/privacy>

- Useful addons:
  - NOTE: This page used to have [onionflare](https://github.com/T0astBread/onionflare) listed here. The project readme now says "It seems that newer versions of Firefox don't need this add-on anymore to pass CAPTCHA-free on websites behind Cloudflare. It is recommended to uninstall this extension..."
  - [NoScript Security Suite](https://addons.mozilla.org/en-US/firefox/addon/noscript/) - Disable most of JavaScript by default; little bit inconvenient for new users
  - [I still don't care about cookies](https://addons.mozilla.org/en-US/firefox/addon/istilldontcareaboutcookies/) - Skips cookie popups
  - [Privacy Redirect](https://addons.mozilla.org/en-US/firefox/addon/privacy-redirect/) - Redirect common nonfree service urls with their Free Software proxied versions (Invidious for YT, libreddit for Reddit, Nitter for Twitter etc.)

**Ref:**

- [How to write FreeBSD image to USB disk for installation](https://www.cyberciti.biz/faq/how-to-write-freebsd-image-to-usb-disk-for-installation-using-dd-command/)
- [https://forums.freebsd.org/threads/does-freebsd-use-uuid-to-identify-partitions.31078/](https://forums.freebsd.org/threads/does-freebsd-use-uuid-to-identify-partitions.31078/)
- [https://forums.freebsd.org/threads/adding-a-label-to-a-live-partition.79429/](https://forums.freebsd.org/threads/adding-a-label-to-a-live-partition.79429/)
- [https://docs.freebsd.org/en_US.ISO8859-1/books/handbook/geom-glabel.html](https://docs.freebsd.org/en_US.ISO8859-1/books/handbook/geom-glabel.html)
- [http://www.wonkity.com/~wblock/docs/html/labels.html](http://www.wonkity.com/~wblock/docs/html/labels.html)
